package com.chenfan.process.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenfan.process.common.constants.CommonFieldConstants;
import com.chenfan.process.common.utils.QueryWrapperUtils;
import com.chenfan.process.entity.dto.ApprovalQueryDTO;
import com.chenfan.process.entity.dto.RefreshDataDTO;
import com.chenfan.process.entity.po.ApprovalPo;
import com.chenfan.process.enums.ProcessEnums;
import com.chenfan.process.repository.ApprovalRepository;
import com.chenfan.process.service.ApprovalService;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author K
 * @date 2021/3/3
 */
@Service
public class ApprovalServiceImpl extends ServiceImpl<ApprovalRepository, ApprovalPo> implements ApprovalService {

    @Override
    public ApprovalPo findApprovalByApprovalId(Long approvalId) {
        QueryWrapper<ApprovalPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ApprovalPo.APPROVAL_ID, approvalId);
        return getOne(queryWrapper);
    }

    @Override
    public ApprovalPo findApprovalByApprovalIdWithoutTenantId(Long approvalId) {
        QueryWrapper<ApprovalPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ApprovalPo.APPROVAL_ID, approvalId);
        return getOne(queryWrapper);
    }

    @Override
    public List<ApprovalPo> listApprovalListWithoutOption(Collection<Long> approvalIdList) {
        QueryWrapper<ApprovalPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(ApprovalPo.APPROVAL_ID, approvalIdList);
        return list(queryWrapper);
    }

    @Override
    public List<ApprovalPo> pageApproval(ApprovalPo approvalPo, Integer pageNum, Integer pageSize) {
        Page<ApprovalPo> page = new Page<>(pageNum, pageSize);
        QueryWrapper<ApprovalPo> queryWrapper = QueryWrapperUtils.newQueryWrapper();
        queryWrapper.eq(!StringUtils.isEmpty(approvalPo.getServiceName()), ApprovalPo.SERVICE_NAME,
            approvalPo.getServiceName());
        queryWrapper.eq(ApprovalPo.STATUS, approvalPo.getStatus());
        queryWrapper.eq(ApprovalPo.APPROVAL_TEMPLATE_ID, approvalPo.getApprovalTemplateId());
        queryWrapper.apply(Objects.nonNull(approvalPo.getUserId()),
            String.format("find_in_set(%s, user_id)", approvalPo.getUserId()));
        return this.page(page, queryWrapper).getRecords();
    }

    @Override
    public Page<ApprovalPo> pageApproval(ApprovalQueryDTO approvalQueryDTO) {
        Page page = new Page(approvalQueryDTO.getPageNum(), approvalQueryDTO.getPageSize());
        QueryWrapper<ApprovalPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Objects.nonNull(approvalQueryDTO.getApprovalTemplateId()), ApprovalPo.APPROVAL_TEMPLATE_ID, approvalQueryDTO.getApprovalTemplateId());
        queryWrapper.eq(!StringUtils.isEmpty(approvalQueryDTO.getBusinessCode()), ApprovalPo.BUSINESS_CODE, approvalQueryDTO.getBusinessCode());
        queryWrapper.in(!CollectionUtils.isEmpty(approvalQueryDTO.getBusinessCodeList()), ApprovalPo.BUSINESS_CODE, approvalQueryDTO.getBusinessCodeList());
        queryWrapper.like(!StringUtils.isEmpty(approvalQueryDTO.getCreateName()), CommonFieldConstants.CREATE_NAME, approvalQueryDTO.getCreateName());
        queryWrapper.ge(Objects.nonNull(approvalQueryDTO.getCreateTimeStart()), CommonFieldConstants.CREATE_TIME, approvalQueryDTO.getCreateTimeStart());
        queryWrapper.le(Objects.nonNull(approvalQueryDTO.getCreateTimeEnd()), CommonFieldConstants.CREATE_TIME, approvalQueryDTO.getCreateTimeEnd());

        // 未传递此参数时默认查出审批中的数据
        queryWrapper.eq(Objects.isNull(approvalQueryDTO.getStatusList()), ApprovalPo.STATUS, ProcessEnums.APPROVING.getCode());

        // 带状态查询
        queryWrapper.in(!CollectionUtils.isEmpty(approvalQueryDTO.getStatusList()), ApprovalPo.STATUS, approvalQueryDTO.getStatusList());
        if (!CollectionUtils.isEmpty(approvalQueryDTO.getUserIdList())) {
            queryWrapper.and(e -> {
                for (int i = 0; i < approvalQueryDTO.getUserIdList().size(); i++) {
                    if (i == 0) {
                        e.apply(String.format("find_in_set(%s, user_id)", approvalQueryDTO.getUserIdList().get(i)));
                    } else {
                        e.or().apply(String.format("find_in_set(%s, user_id)", approvalQueryDTO.getUserIdList().get(i)));
                    }
                }
            });
            // 不带状态查询
            queryWrapper.eq(CollectionUtils.isEmpty(approvalQueryDTO.getStatusList()), ApprovalPo.STATUS, ProcessEnums.APPROVING.getCode());
        }
        queryWrapper.orderByDesc(CommonFieldConstants.CREATE_TIME);
        return this.page(page, queryWrapper);
    }

    @Override
    public List<ApprovalPo> pageApproval(ApprovalPo approvalPo, List<Long> templateIdList, List<Long> userIdList, Integer pageNum, Integer pageSize) {
        Page<ApprovalPo> page = new Page<>(pageNum, pageSize);
        QueryWrapper<ApprovalPo> queryWrapper = QueryWrapperUtils.newQueryWrapper();
        queryWrapper.eq(ApprovalPo.APPROVAL_TEMPLATE_ID, approvalPo.getApprovalTemplateId());
        queryWrapper.in(!CollectionUtils.isEmpty(templateIdList), ApprovalPo.APPROVAL_TEMPLATE_ID, templateIdList);
        queryWrapper.eq(ApprovalPo.STATUS, approvalPo.getStatus());
        queryWrapper.eq(!StringUtils.isEmpty(approvalPo.getServiceName()), ApprovalPo.SERVICE_NAME,
                approvalPo.getServiceName());

        if (!CollectionUtils.isEmpty(userIdList)) {
            queryWrapper.and(e -> {
                for (int i = 0; i < userIdList.size(); i++) {
                    if (i == 0) {
                        e.apply(String.format("find_in_set(%s, user_id)", userIdList.get(i)));
                    } else {
                        e.or().apply(String.format("find_in_set(%s, user_id)", userIdList.get(i)));
                    }
                }
            });
        }

        return this.page(page, queryWrapper).getRecords();
    }

    @Override
    public List<ApprovalPo> findApprovalList(Collection<Long> approvalIdList) {
        QueryWrapper<ApprovalPo> queryWrapper = QueryWrapperUtils.newQueryWrapper();
        queryWrapper.in(ApprovalPo.APPROVAL_ID, approvalIdList);
        // queryWrapper.eq(ApprovalPo.STATUS, ProcessEnums.APPROVING.getCode());
        return list(queryWrapper);
    }

    @Override
    public List<ApprovalPo> listApproving(Long templateId, List<Long> versionList,
                                          List<Long> approvalIdList,
                                          Date startDate, Date endDate) {
        QueryWrapper<ApprovalPo> queryWrapper = QueryWrapperUtils.newQueryWrapper();
        queryWrapper.eq(ApprovalPo.APPROVAL_TEMPLATE_ID, templateId);
        queryWrapper.in(!CollectionUtils.isEmpty(versionList), ApprovalPo.VERSION, versionList);
        queryWrapper.eq(ApprovalPo.STATUS, ProcessEnums.APPROVING.getCode());
        queryWrapper.in(!CollectionUtils.isEmpty(approvalIdList), ApprovalPo.APPROVAL_ID, approvalIdList);
        queryWrapper.ge(Objects.nonNull(startDate), ApprovalPo.CREATE_TIME, startDate);
        queryWrapper.le(Objects.nonNull(endDate), ApprovalPo.CREATE_TIME, endDate);
        queryWrapper.orderByAsc(ApprovalPo.VERSION);
        return list(queryWrapper);
    }

    @Override
    public boolean checkApproval(Long templateId) {
        QueryWrapper<ApprovalPo> queryWrapper = QueryWrapperUtils.newQueryWrapper();
        queryWrapper.eq(ApprovalPo.APPROVAL_TEMPLATE_ID, templateId);
        return !this.list(queryWrapper).isEmpty();
    }

    @Override
    public List<ApprovalPo> listWithTemplateList(List<Long> approvalTemplateIdList) {
        QueryWrapper<ApprovalPo> queryWrapper = QueryWrapperUtils.newQueryWrapper();
        queryWrapper.in(ApprovalPo.APPROVAL_TEMPLATE_ID, approvalTemplateIdList);
        return list(queryWrapper);
    }

    @Override
    public List<ApprovalPo> listDataFromStartAndEnd(RefreshDataDTO refreshData) {
        QueryWrapper<ApprovalPo> queryWrapper = QueryWrapperUtils.newQueryWrapper();
        queryWrapper.ge(CommonFieldConstants.ID, refreshData.getStartPosition());
        queryWrapper.le(Objects.nonNull(refreshData.getStep()), CommonFieldConstants.ID, refreshData.getStartPosition() + refreshData.getStep());
        queryWrapper.le(Objects.nonNull(refreshData.getEndPosition()), CommonFieldConstants.ID, refreshData.getEndPosition());
        return this.list(queryWrapper);
    }

    @Override
    public List<ApprovalPo> findByTemplateIdAndBusiness(Long id, Long businessId, String businessCode) {
        LambdaQueryWrapper<ApprovalPo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ApprovalPo::getApprovalTemplateId, id);
        lambdaQueryWrapper.eq(ApprovalPo::getBusinessId, businessId);
        lambdaQueryWrapper.eq(ApprovalPo::getBusinessCode, businessCode);
        lambdaQueryWrapper.eq(ApprovalPo::getStatus, ProcessEnums.APPROVING.getCode());
        lambdaQueryWrapper.eq(ApprovalPo::getDeletedFlag, Boolean.FALSE);
        return this.list(lambdaQueryWrapper);
    }
}
